{
File ResXXXXEd.p

Copyright Apple Computer, Inc. 1985-1989
All rights reserved.
}

UNIT ResXXXXed;
{XXXX Editor for ResEdit}

INTERFACE

	USES	Memtypes, QuickDraw, OSIntf, ToolIntf, PackIntf,
				ResEd;

		{$R-} {Range checking off }

	TYPE
		rXXXXPtr = ^rXXXXRec;
		rXXXXHandle = ^rXXXXPtr;
		rXXXXRec = RECORD
								 father: ParentHandle;	{ Back ptr to dad }
								 name: str64; 					{ The name of this editor }
								 windPtr: WindowPtr;		{ This view's window }
								 rebuild: BOOLEAN;			{ Set TRUE if things have changed }
								 hXXXX: Handle;					{ The resource we are working on }
							 END; {rXXXXRec}

	PROCEDURE EditBirth(thing: Handle; Dad: ParentHandle);

	PROCEDURE PickBirth(t: ResType; Dad: ParentHandle);

	PROCEDURE DoEvent(VAR Evt: EventRecord; myXXXX: rXXXXHandle);

	PROCEDURE DoInfoUpdate(oldID, newID: INTEGER; myXXXX: rXXXXHandle);

	PROCEDURE DoMenu(Menu, Item: INTEGER; myXXXX: rXXXXHandle);

IMPLEMENTATION

	CONST
		windowWidth = 300;
		windowHeight = 100;

		deleteChr = CHR(8);
		
		sizeOfMyResource = 10;
		
		{- - -	-  - -	-  -	- -  -	- - -  - -	- - -  -	- -  -	-}

	{ Fix up the window name and title for our window. }
	PROCEDURE GetNameAndTitle(VAR windowTitle, windowName: STR255; thing: Handle);

		BEGIN
		windowTitle := '';
		SetETitle(thing, windowTitle);
		windowName := Concat('XXXX', windowTitle);
		windowTitle := Concat('XXXX', windowTitle);
		END;

 { **************************************************************************************** }

	PROCEDURE EditBirth(thing:Handle; dad:ParentHandle);

		VAR
			myXXXX: rXXXXHandle;
			myWindow: WindowPtr;
			windowTitle, newName: STR255;

		BEGIN {EditBirth}
		{ Prepare window title and request creation of a new window }
		GetNameAndTitle(windowTitle, newName, thing);
		myWindow := EditorWindSetup(FALSE, windowWidth, windowHeight, windowTitle, newName, TRUE, dad);
		
		{ If we got a new window, then start up the editor }
		IF myWindow <> NIL THEN
			BEGIN
			IF (GetHandleSize(thing)) = 0 THEN { This was called via a NEW, so make a new resource }
				FixHand(sizeOfMyResource, thing);

			{ Get memory for and handle to our instance record }
			myXXXX := rXXXXHandle(NewHandle(SIZEOF(rXXXXRec)));
			BubbleUp(Handle(myXXXX));
			HLock(Handle(myXXXX));

			WITH myXXXX^^ DO
				BEGIN
				{ Put information about this incarnation of the editor and the window it is }
				{ serving into our record.(always passed around in the handle myXXXX).  }
				
				windPtr := myWindow;
				father := dad;
				name := newName;
				hXXXX := thing;
				
				{ Let the main program know who is to manage this window by giving it both 	}
				{ our resource ID number and our instance record handle.		}
				WITH WindowPeek(myWindow)^ DO
					BEGIN
					windowKind := ResEdID;
					refCon := ORD(myXXXX);
					END; {WITH}
				END; {WITH}
				
			{ Set up any menus,views, etc. for this window here. }
			
			HUnlock(Handle(myXXXX));
			END; { IF myWind <> NIL }
		END; { EditBirth }
	{- -	-  - - -	- -  - - -	-  - -	-  -	- -  -	- - -  - -}

	{ Not used for editors. }
	PROCEDURE PickBirth(t:ResType;Dad:ParentHandle);

		BEGIN { PickBirth }
		END; 	{ PickBirth }
	{- -	-  - - -	- -  - - -	-  - -	-  -	- -  -	- - -  - -}

	PROCEDURE DoEvent(VAR Evt:EventRecord; myXXXX:rXXXXHandle);

		VAR
			MousePoint: Point;
			act: BOOLEAN;

		BEGIN {DoEvent}
		BubbleUp(Handle(myXXXX)); 		{ Move our item up in memory }
		HLock(Handle(myXXXX)); 				{ Lock it down }
		WITH myXXXX^^ DO
			BEGIN
			{ Handle event passed to us by main program.  Just like a 'real' event loop, exceptÉ
				 there is no loop and we don't have to handle as much because the main program
				 will do all the stuff that doesn't apply to us. }
				
			MousePoint := Evt.where;		{ Point at which the event occured }
			SetPort(windPtr);						{ Set the port to our window }
			GlobalToLocal(MousePoint);	{ Convert event location to local coords }
			
			CASE Evt.what OF
				mouseDown:
					BEGIN
												{ Do any special mouse down processing here. }
					END; { mouseDown }
				activateEvt:
					BEGIN
					AbleMenu(fileMenu, filetop);
					act := ODD(Evt.modifiers);
					IF act THEN
						BEGIN
												{ Do any activate processing here (such as inserting a menu). }
						END
					ELSE
						BEGIN
												{ Do any deactivate processing here (such as deleting a menu). }
						END;
					DrawMenuBar;	{ To make sure that everything is drawn properly. }
					END {activateEvt} ;
				updateEvt:
					BEGIN
												{ Do the appropriate update processing here.  Remember that 
													BeginUpdate has already been called. }
					PaintRect(windPtr^.portrect);
					END; {updateEvt}
				keyDown:
					BEGIN
												{ Do any key processing here. }
					
					{ Convert the delete character into a clear command. }
					IF (CHR(band(evt.message, charCodeMask)) = deleteChr) THEN
						DoMenu (editMenu, clearItem, myXXXX)
					END; {keyDown}
				
				nullEvent:
					BEGIN
											{ Do any null event processing here (such as blinking a cursor).	}
					END;
				END;	{ CASE evt.what }
			END; 		{ WITH myXXXX^^ }
			
		HUnlock(Handle(myXXXX));
		END; 			{ DoEvent }
	{- -	-  - - -	- -  - - -	-  - -	-  -	- -  -	- - -  - -}

	PROCEDURE DoInfoUpdate(oldID,newID:INTEGER;myXXXX:rXXXXHandle);

		VAR
			windowTitle, windowName: STR255;

		BEGIN { DoInfoUpdate }
		WITH myXXXX^^ DO
			BEGIN 
			{ Since our ID has changed, we need to change our window title }
			GetNameAndTitle (windowTitle, windowName, Handle(hXXXX));
			GetWindowTitle (windowTitle, windowName, TRUE, father);
			name := windowName;								{ Save the new name in my data structure. }
			SetWTitle(windPtr, windowtitle);	{ Set the new window title. }
	
			{ Now, let our father object know that our ID has been changed }
			father^^.rebuild := TRUE;					{ Rebuild the picker list. }
			CallInfoUpdate(oldID, newID, father^^.wind^.refCon, father^^.wind^.windowKind);
			END; { WITH myXXXX^^ }
		END; { DoInfoUpdate }
	{- -	-  - - -	- -  - - -	-  - -	-  -	- -  -	- - -  - -}

	PROCEDURE DoMenu(Menu, Item:INTEGER; myXXXX:rXXXXHandle);

		VAR
			saveRefNum: INTEGER;
			hTemp: Handle;

		{ Close down the window and get rid of any memory that has been allocated. }
		PROCEDURE DoClose;

			BEGIN
			WITH myXXXX^^ DO
				BEGIN
				CloseWindow(windPtr);
				WindReturn(windPtr);				{ Mark the window record as being available }
				SetTheCursor (arrowCursor); { Make sure the cursor is the arrow cursor }
				
				{ Delete any menus that we added and the redraw menu bar 	}
				{ Be sure to dispose of any handles you are done with	}
				
				{ Release the resource if we were launched from a picker }
				IF (father^^.name[1] <> editorNameChr) THEN
					ReleaseResource (Handle(hXXXX));  { Let it be free (if it is not changed)! }
				END; { WITH myXXXX^^ }
			DisposHandle(Handle(myXXXX));
			END; { DoClose }

		BEGIN {DoMenu}
		BubbleUp(Handle(myXXXX));
		HLock(Handle(myXXXX));
		WITH myXXXX^^ DO
			BEGIN
			SetPort(windPtr); { Set the port to our window }
			
			{ Again, we handle the menu stuff just as we would in a 'real' application
				except that we only have to handle those items that apply to our editor. }
			CASE Menu OF
				fileMenu:
					CASE Item OF
						CloseItem:
							BEGIN
							DoClose; 			{	Close our window }
							EXIT(DoMenu); {	Return immediately since our resource is gone!	}
							END; { CloseItem }
							
						saveItem:				{ Pass the save on to other windows. }
							PassMenu(fileMenu, saveItem, ParentHandle(myXXXX));
				
						RevertItem:
							BEGIN
							IF NeedToRevert (windPtr, Handle(hXXXX)) THEN
								BEGIN
								{ The area under the window will need to be updated }
								InvalRect(windPtr^.portrect);
								
								{ We will need to restore the current resource file reference number when we are done here.	 }
								saveRefNum := CurrentRes;
								{ We are going to be using the resource file we came from. }
								UseResFile(HomeResFile(Handle(hXXXX)));
								
								{ Read in the old copy from disk (see documentation for revertResource).  Clear it out 
									unless this  was a newly created resource, in which case don't. }
								IF NOT RevertThisResource(ParentHandle(myXXXX), Handle(hXXXX)) THEN
									BEGIN		{ The resource was newly added so we need to remove it. }
									{ Save the handle so that we can dispose it later. }
									hTemp := Handle (hXXXX);
									
									{ Make sure that the picker list is rebuilt to remove this item. }
									myXXXX^^.father^^.rebuild := TRUE;
									
									DoClose;								{ Close the window. }
									RemoveResource (hTemp);	{ Dispose the resource itself. }
									EXIT(DoMenu);
									END; {IF NOT RevertResourceÉ}
								
								UseResFile(saveRefNum);	{ Go back to using the old resource file. }
								END;
							END; { RevertItem }
							
						GetInfoItem:
							BEGIN
							{ Put up the GetInfo window. }
							ShowInfo(Handle(hXXXX), ParentHandle(myXXXX));
							END; { GetInfoItem }
					END; {FileMenu: CASE Item OF}
				EditMenu:
					CASE Item OF
						{ Implement the edit menu here. }
						CutItem: ;
						CopyItem: ;
						PasteItem: ;
						ClearItem: ;
					END; { EditMenu }
				END; { CASE Menu OF }
			END; { WITH myXXXX^^}
		HUnlock(Handle(myXXXX));
		END; {DoMenu}
END.
